using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace LeanUi.ImageBundle
{
    public class ImageProxyGenerator 
    {
        public string GenerateImageBundleSource(IList<ImageRect> imageRects, DirectoryInfo baseDir, string baseNameSpace, string css)
        {
            var groupedByBundle = imageRects.ToLookup(x => x.BundleName);
            string[] classes = groupedByBundle
                .OrderBy( g => g.Key)
                .Select( g => GenerateProxyClass(g.ToList(), baseDir))
                .ToArray();

           string[] bundleNames = groupedByBundle
                .OrderBy( g => g.Key)
                .Select( g => g.Key )
                .ToArray();

            const string fullBundleName = "ImageBundle";
            var mainclass = string.Format(CodeGenerationTemplates.ImageBundleClassTemplate,
                                          fullBundleName,
                                          Join(bundleNames, CodeGenerationTemplates.ImageBundleSingletonTemplate),
                                          Join(bundleNames, CodeGenerationTemplates.DynamicAccessTemplate),
                                          css.Replace("\"", "\"\""));

            return string.Format(CodeGenerationTemplates.NamespaceTemplate,
                                 baseNameSpace,
                                 mainclass,
                                 Join(classes));
        }

        public string GenerateProxyClass( IEnumerable<ImageRect> imageRects, DirectoryInfo baseDir )
        {
            if (!imageRects.Any()) return "";

            var basePath = baseDir.FullName;
            var bundleName = imageRects.First().BundleName;
            var props = imageRects.Where( img=> !img.IsDisabledSprite() )
                                  .Select( img => GenerateProperty(img, basePath) )
                                  .OrderBy(x => x)
                                  .ToArray();

            var mappings = imageRects.Where( img=> !img.IsDisabledSprite() )
                                     .Select( GenerateDynamicAccess )
                                     .ToArray();

            return string.Format(CodeGenerationTemplates.ClassTemplate,
                    bundleName,
                    Join( props ),
                    Join( mappings ));
        }

        private string Join(IEnumerable<string> list, string template)
        {
            return Join( list.Select(x => string.Format(template, x)).ToArray() );
        }

        private string Join(string[] source)
        {
            return string.Join(Environment.NewLine, source);
        }

        private string GenerateDynamicAccess(ImageRect image)
        {
            return string.Format(CodeGenerationTemplates.DynamicAccessTemplate, image.Name);
        }

        private string GenerateProperty(ImageRect image, string basepath)
        {
            string relativePath = PathHelper.RelativePathToFile(basepath, image.FullPath).Replace("\\", "/");
            return string.Format(CodeGenerationTemplates.PropertyTemplate, image.Name, relativePath);
        }
    }
}